﻿namespace EyeOpen.SilverlightConverter
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Xml.Linq;

    public partial class VisualStudioProjectConverter
    {
        private XElement ConvertWindowsLibraryToSilverlight(XElement projectXElement)
        {
            XElement convertedProjectXElement = new XElement(projectXElement);

            this.ChangePropertyGroupItems(convertedProjectXElement);

            this.RemoveAndAddReferences(convertedProjectXElement);

            this.ChangeTargets(convertedProjectXElement);

            return convertedProjectXElement;
        }

        private void RemoveAndAddReferences(XElement convertedProjectXElement)
        {
            IEnumerable<XElement> itemGroups = convertedProjectXElement.GetNodesFromName("ItemGroup");

            string includeAttribute = "Include";

            foreach (XElement itemGroup in itemGroups)
            {
                ////Remove all System references
                IEnumerable<XElement> includeReferences =
                    from reference in itemGroup.GetNodesFromName("Reference")
                    where reference.Attribute(includeAttribute).Value != null
                    && (reference.Attribute(includeAttribute).Value.StartsWith("System.")
                    || reference.Attribute(includeAttribute).Value == "System")
                    select reference;

                if (includeReferences.Count() > 0)
                {
                    includeReferences.Remove();
                    this.AddSilverlightIncludes(itemGroup);
                }
            }
        }

        private void AddSilverlightIncludes(XElement itemGroup)
        {
            string referenceName = "Reference";
            string includeName = "Include";

            itemGroup.AddNodeWithAttribute(this.Xnsp, referenceName, includeName, "System.Windows");
            itemGroup.AddNodeWithAttribute(this.Xnsp, referenceName, includeName, "mscorlib");
            itemGroup.AddNodeWithAttribute(this.Xnsp, referenceName, includeName, "system");
            itemGroup.AddNodeWithAttribute(this.Xnsp, referenceName, includeName, "System.Core");
            itemGroup.AddNodeWithAttribute(this.Xnsp, referenceName, includeName, "System.Xml");
            itemGroup.AddNodeWithAttribute(this.Xnsp, referenceName, includeName, "System.Net");
            itemGroup.AddNodeWithAttribute(this.Xnsp, referenceName, includeName, "System.Windows.Browser");
        }

        private void ChangePropertyGroupItems(XElement convertedProjectXElement)
        {
            IEnumerable<XElement> propertyGroups = convertedProjectXElement.GetNodesFromName("PropertyGroup");

            foreach (XElement propertyGroup in propertyGroups)
            {
                this.RemoveFileAlignment(propertyGroup);

                XAttribute condition = propertyGroup.Attribute("Condition");

                if (condition != null)
                {
                    if (condition.Value == DebugCondition)
                    {
                        propertyGroup.GetNodesFromName(DefineConstants)
                        .First()
                        .Value = "DEBUG;TRACE;SILVERLIGHT";
                    }

                    if (condition.Value == ReleaseCondition)
                    {
                        propertyGroup.GetNodesFromName(DefineConstants)
                        .First()
                        .Value = "TRACE;SILVERLIGHT";
                    }

                    this.AddNoItem(propertyGroup);
                }
                else
                {
                    string projectTypeGuids = "{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}";
                    propertyGroup.AddNodeWithValue(this.Xnsp, "ProjectTypeGuids", projectTypeGuids);
                }
            }
        }

        private void ChangeTargets(XElement convertedProjectXElement)
        {
            XElement importXElement = convertedProjectXElement.GetNodesFromName("Import")
                                      .FirstOrDefault();

            importXElement.Attribute("Project").Value = @"$(MSBuildExtensionsPath)\Microsoft\Silverlight\v3.0\Microsoft.Silverlight.CSharp.targets";
        }

        private bool RemoveFileAlignment(XElement propertyGroup)
        {
            XElement fileAlignmentXElement =
                propertyGroup.GetNodesFromName("FileAlignment")
                .FirstOrDefault();

            if (fileAlignmentXElement != null)
            {
                this.AddSilverlightPropertyGroupItems(propertyGroup);
                fileAlignmentXElement.Remove();
            }

            return fileAlignmentXElement != null;
        }

        private void AddSilverlightPropertyGroupItems(XElement propertyGroup)
        {
            propertyGroup.AddNodeWithValue(this.Xnsp, "SilverlightApplication", "false");
            propertyGroup.AddNodeWithValue(this.Xnsp, "ValidateXaml", "true");
            propertyGroup.AddNodeWithValue(this.Xnsp, "ThrowErrorsInValidation", "true");
        }

        private void AddNoItem(XElement propertyGroup)
        {
            propertyGroup.AddNodeWithValue(this.Xnsp, "NoStdLib", "true");
            propertyGroup.AddNodeWithValue(this.Xnsp, "NoStdLib", "true");
        }
    }
}